package cate.game.rank.po;

import cate.game.role.Role;
import cate.game.role.RoleSnapshot;
import easy.java.dev.note.NoteField;

import java.util.Comparator;

public class ExtraValueRankSPO extends RankSPO<Rank>{
    @NoteField(value = "类型")
    public Type type = Type.VALUE_BIG_EXTRA_BIG_NIUBI;

    public ExtraValueRankSPO(){

    }

    public ExtraValueRankSPO(Type type){
        this.type = type;
    }

    protected boolean failCompareToLastOne(long lastValue, long lastExtraValue, long value, long extraValue){
        boolean fail = false;
        if(type == Type.VALUE_BIG_EXTRA_BIG_NIUBI){
            fail = lastValue > value || (lastValue == value && lastExtraValue >= extraValue);
        }else if(type == Type.VALUE_BIG_EXTRA_SMALL_NIUBI){
            fail = lastValue > value || (lastValue == value && lastExtraValue <= extraValue);
        }else if(type == Type.VALUE_SMALL_EXTRA_BIG_NIUBI){
            fail = lastValue < value || (lastValue == value && lastExtraValue >= extraValue);
        }else if(type == Type.VALUE_SMALL_EXTRA_SMALL_NIUBI){
            fail = lastValue < value || (lastValue == value && lastExtraValue <= extraValue);
        }
        return fail;
    }

    public boolean canInRank(int value , long extraValue){
        if (list.size() >= getRankNum()) {
            Rank last = list.get(list.size() - 1);
            if (failCompareToLastOne(last.value, last.extraValue, value, extraValue)) {
                // 没有进排行榜
                return false;
            }
        }
        return true;
    }

    /**
     * 默认value大 extravalue大的牛逼
     * @param role role
     * @param value 参数1
     * @param extraValue 参数2
     * @param sort 是否排序
     */
    public void record(Role role, int value, long extraValue, boolean sort){
        if (!canInRank(value, extraValue)) {
            return;
        }
        // 是否已经上榜
        Rank item = findByRoleUid(role.getUid());
        long preValue = item == null ? 0 : item.value;
        long preExtraValue = item == null ? 0 : item.extraValue;
        if (item != null) {
            item.updateOwner(role, value, extraValue);
        } else {
            // 之前没有上榜
            Rank e = new Rank(role, value, extraValue);
            if (list.size() >= getRankNum()) {
                // 如果排行榜已经满了，那就把最后一名给去掉
                list.remove(list.size() - 1);
            }
            list.add(e);
        }
        if(sort && (preValue != value || preExtraValue != extraValue)){
            sort(type);
        }
    }

    /**
     * 默认value大 extravalue大的牛逼
     * @param rs rs
     * @param value 参数1
     * @param extraValue 参数2
     * @param sort 是否排序
     */
    public void record(RoleSnapshot rs, int value, long extraValue, boolean sort){
        if (list.size() >= getRankNum()) {
            Rank last = list.get(list.size() - 1);
            if (failCompareToLastOne(last.value, last.extraValue, value, extraValue)) {
                // 没有进排行榜
                return;
            }
        }
        // 是否已经上榜
        Rank item = findByRoleUid(rs.uid);
        long preValue = item == null ? 0 : item.value;
        long preExtraValue = item == null ? 0 : item.extraValue;
        if (item != null) {
            // 已经在榜上了
            item.updateOwner(rs, value, extraValue);
        } else {
            // 之前没有上榜
            Rank e = new Rank(rs, value, extraValue);
            if (list.size() >= getRankNum()) {
                // 如果排行榜已经满了，那就把最后一名给去掉
                list.remove(list.size() - 1);
            }
            list.add(e);
        }
        if(sort && (preValue != value || preExtraValue != extraValue)){
            sort(type);
        }
    }

    @Override
    public void sort(){
        sort(Type.VALUE_BIG_EXTRA_BIG_NIUBI);
    }

    public void sort(Type type){
        list.sort(typeComparator(type).thenComparing(Rank::getRecordTime));
    }

    protected Comparator<Rank> typeComparator(Type type){
        if(type == Type.VALUE_BIG_EXTRA_BIG_NIUBI){
            return Comparator.comparing(Rank::getValue)
                    .thenComparing(Rank::getExtraValue)
                    .reversed();
        }else if(type == Type.VALUE_BIG_EXTRA_SMALL_NIUBI){
            return Comparator.comparing(Rank::getValue)
                    .reversed()
                    .thenComparing(Rank::getExtraValue);
        }else if(type == Type.VALUE_SMALL_EXTRA_SMALL_NIUBI){
            return Comparator.comparing(Rank::getValue)
                    .thenComparing(Rank::getExtraValue);
        }else{
            //这个不确定，没试过
            return Comparator.comparing(Rank::getValue)
                    .reversed()
                    .thenComparing(Rank::getExtraValue)
                    .reversed();
        }
    }

    /**
     * 排序类型
     */
    public enum Type{
        /** value大的，extraValue大的牛逼 */
        VALUE_BIG_EXTRA_BIG_NIUBI,
        /** value小的， extraValue 大的牛逼 */
        VALUE_SMALL_EXTRA_BIG_NIUBI,
        /** value大的，extraValue小的牛逼 */
        VALUE_BIG_EXTRA_SMALL_NIUBI,
        /** value小的，extraValue小的牛逼 */
        VALUE_SMALL_EXTRA_SMALL_NIUBI
    }
}
